from common_data import *
from permission import *
from twisted.web import xmlrpc
from twisted.python import log

class XMLRPC_DNSServerConfig( xmlrpc.XMLRPC ):
    _permissions = {
        'listDNSServerConfig':                      PERMISSION_REQUIREMENT_GLOBAL_ADMIN,
        'setDNSServerActiveListRefreshInterval':    PERMISSION_REQUIREMENT_GLOBAL_ADMIN,
        'setDNSServerDenyInactiveIPs':              PERMISSION_REQUIREMENT_GLOBAL_ADMIN,
        'setDNSServerQueryAuthName':                PERMISSION_REQUIREMENT_GLOBAL_ADMIN,
        'addDNSServerResolver':                     PERMISSION_REQUIREMENT_GLOBAL_ADMIN,
        'delDNSServerResolver':                     PERMISSION_REQUIREMENT_GLOBAL_ADMIN,
        'setDNSServerConfigRefreshInterval':        PERMISSION_REQUIREMENT_GLOBAL_ADMIN,
        'setDNSServerTCPPort':                      PERMISSION_REQUIREMENT_GLOBAL_ADMIN,
        'setDNSServerUDPPort':                      PERMISSION_REQUIREMENT_GLOBAL_ADMIN,
    }
    
    def __init__(self):
        """ load config
        """
        log.msg( 'DNSServerConfig resource init' )
        xmlrpc.XMLRPC.__init__(self)

    def xmlrpc_addDNSServerResolver(self, new_hostname, new_port):
        """add a new server used to resolve requests for inactive queries"""
        
        if not str( new_hostname ) or not int( new_port ):
            raise xmlrpc.Fault( 123, 'Invalid arguments' )
        
        current_config = self.getLatestDNSServerConfig()
        
        if current_config:
            try:
                new_resolver = DNSResolver( hostname = str( new_hostname ), port = int( new_port ), config = current_config )
            except:
                log.err( 'could not create new resolver' )
                log.err()
                raise xmlrpc.Fault( 123, 'could not add new resolver' )
                
            current_config.updateModifiedTime()
            
        return True
    
    xmlrpc_addDNSServerResolver.signature = [ ['bool','string','int']]
    
    def xmlrpc_delDNSServerResolver(self, target_hostname, target_port):
        """remove a server used to resolve requests for inactive queries"""
        
        if not str( target_hostname ) or not int( target_port ):
            raise xmlrpc.Fault( 123, 'Invalid arguments' )
        
        current_config = self.getLatestDNSServerConfig()
        
        if current_config:
            for resolver in current_config.resolvers:
                if resolver.hostname == str( target_hostname ) and resolver.port == int( target_port ):
                    resolver.destroySelf()                
                    current_config.updateModifiedTime()
            
        return True
    
    xmlrpc_delDNSServerResolver.signature = [ ['bool','string','int'] ]
    
    def xmlrpc_setDNSServerUDPPort(self, new_udp_port ):
        """define the udp port used to service queries"""
        
        if not int( new_udp_port ):
            raise xmlrpc.Fault( 123, 'Invalid arguments' )
            
        current_config = self.getLatestDNSServerConfig()
        
        if current_config:
            current_config.udp_port = int( new_udp_port )
            current_config.updateModifiedTime()
            
        return True
    
    xmlrpc_setDNSServerUDPPort.signature = [['bool','int']]
    
    def xmlrpc_setDNSServerTCPPort(self, new_tcp_port):
        """define the tcp port used to service queries"""
        
        if not int( new_tcp_port ):
            raise xmlrpc.Fault( 123, 'Invalid arguments' )
            
        current_config = self.getLatestDNSServerConfig()
        
        if current_config:
            current_config.tcp_port = int( new_tcp_port )
            current_config.updateModifiedTime()
            
        return True
    
    xmlrpc_setDNSServerTCPPort.signature = [['bool','int']]
    
    def xmlrpc_setDNSServerDenyInactiveIPs(self, new_setting):
        """define if queries from inactive ips are denied"""
        
        if not int( new_setting ):
            raise xmlrpc.Fault( 123, 'Invalid arguments' )
            
        current_config = self.getLatestDNSServerConfig()
        
        if current_config:
            current_config.deny_inactive_ips = ( int( new_setting ) == 1 and True ) or False
            current_config.updateModifiedTime()
            
        return True
        
    xmlrpc_setDNSServerDenyInactiveIPs.signature = [['bool','int']]
    
    def xmlrpc_setDNSServerConfigRefreshInterval(self, new_interval):
        """define in seconds the interval between server config refreshes"""
        
        if not int( new_interval ):
            raise xmlrpc.Fault( 123, 'Invalid arguments' )
        
        if int( new_interval ) < 1:
            raise xmlrpc.Fault( 123, 'new interval is too small' )
            
        current_config = self.getLatestDNSServerConfig()
        
        if current_config:
            current_config.config_refresh_interval = int( new_interval )
            current_config.updateModifiedTime()
            
        return True
            
    xmlrpc_setDNSServerConfigRefreshInterval.signature = [['bool','int']]
    
    def xmlrpc_setDNSServerActiveListRefreshInterval(self, new_interval ):
        """define in seconds the interval between active ip/checkout refreshes"""
        
        if not int( new_interval ):
            raise xmlrpc.Fault( 123, 'Invalid arguments' )
        
        if int( new_interval ) < 1:
            raise xmlrpc.Fault( 123, 'new interval is too small' )
            
        current_config = self.getLatestDNSServerConfig()
        
        if current_config:
            current_config.active_list_refresh_interval = int( new_interval )
            current_config.updateModifiedTime()
            
        return True
    
    xmlrpc_setDNSServerActiveListRefreshInterval.signature = [['bool','int']]
    
    def xmlrpc_setDNSServerQueryAuthName(self, new_auth_name):
        """define the authoritative name used when responding to redirected queries"""
        
        if not str( new_auth_name ):
            raise xmlrpc.Fault( 123, 'Invalid arguments' )
            
        current_config = self.getLatestDNSServerConfig()
        
        if current_config:
            current_config.auth_name = str( new_auth_name )
            current_config.updateModifiedTime()
            
        return True
    
    xmlrpc_setDNSServerQueryAuthName.signature = [['bool','string']]
    
    def xmlrpc_listDNSServerConfig(self):
        """return a dict of dns server options"""
            
        current_config = self.getLatestDNSServerConfig()
        
        if current_config:        
            return self.dnsConfigResultToDict( current_config )
        else:
            return False
        
    xmlrpc_listDNSServerConfig.signature = [['array']]
        
    def dnsConfigResultToDict(self, config ):
            result = dict()
            result['id'] = config.id 
            result['resolvers'] = ( config.resolvers and list( ( resolver.hostname, resolver.port ) for resolver in config.resolvers ) ) or list()
            result['udp_port'] = config.udp_port
            result['tcp_port'] = config.tcp_port
            result['config_refresh_interval'] = config.config_refresh_interval
            result['active_list_refresh_interval'] = config.active_list_refresh_interval
            result['deny_inactive_ips'] = config.deny_inactive_ips
            result['auth_name'] = ( config.auth_name and config.auth_name ) or ""
            
            result['creation_time'] = xmlrpc.DateTime( config.creation_time ).value
            result['modified_time'] = xmlrpc.DateTime( config.modified_time ).value
            
            return result
        
    def getLatestDNSServerConfig(self):
        
        try:
            current_config = DNSServerConfig.select( orderBy=DNSServerConfig.q.creation_time ).reversed().limit(1).getOne()
        except:
            log.err( 'could not retrieve current dns server config' )
            log.err()
            return False
        
        return current_config
        